package com.lucy.rabc.service.impl;

import cn.hutool.core.lang.Validator;
import com.lucy.common.constant.HttpStatus;
import com.lucy.common.domain.PageResultDTO;
import com.lucy.common.exception.BusinessException;
import com.lucy.rabc.constant.MenuTypeEnum;
import com.lucy.rabc.dao.SysMenuDAO;
import com.lucy.rabc.domain.vo.MetaVO;
import com.lucy.rabc.domain.vo.RouterVO;
import com.lucy.rabc.entity.SysMenu;
import com.lucy.rabc.service.SysMenuService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.*;

@Slf4j
@Service
public class SysMenuServiceImpl implements SysMenuService {
    @Autowired
    SysMenuDAO dao;

    @Override
    public PageResultDTO<SysMenu> getAll(Pageable pageable, Example<SysMenu> example) {
        Page<SysMenu> page;

        if(Validator.isEmpty(example)){
            page = dao.findAll(pageable);
        }
        else {
            page = dao.findAll(example,pageable);
        }
        /*
          获取分页主体内容
         */
        List<SysMenu> list = page.getContent();
        PageResultDTO<SysMenu> pageResultDTO = new PageResultDTO<>();


        //封装分页请求结果
        pageResultDTO.setContent(list);
        pageResultDTO.setSize(page.getSize());
        pageResultDTO.setTotalPages(page.getTotalPages());
        pageResultDTO.setNumber(page.getNumber());
        pageResultDTO.setTotalElements(page.getTotalElements());
        return pageResultDTO;
    }

    @Override
    public List<SysMenu> getExample(Example<SysMenu> example) {
        return dao.findAll(example);
    }

    @Override
    public void deleteOne(Long id) {
        dao.deleteById(id);
    }

    @Override
    public Optional<SysMenu> getOne(Long id) {
        return dao.findById(id);
    }

    @Override
    public SysMenu saveOne(SysMenu o) {
        if (Validator.isNotEmpty(o.getId())){
            throw new BusinessException(HttpStatus.BAD_REQUEST,"新建菜单DTO不可携带ID");
        }
        return dao.save(o);
    }

    @Override
    public SysMenu updateOne(SysMenu o) {
        if (Validator.isEmpty(o.getId())){
            throw new BusinessException(HttpStatus.BAD_REQUEST,"更新菜单DTO必须携带ID");
        }
        return dao.save(o);
    }

    @Override
    public List<SysMenu> getMenus(List<Long> menuIds) {
        return dao.findByIdIn(menuIds);
    }


    @Override
    public List<RouterVO> buildMenus(List<SysMenu> menus) {
        List<RouterVO> routers = new LinkedList<RouterVO>();

        for(SysMenu menu:menus){
            RouterVO routerVO = new RouterVO();
            routerVO.setName(menu.getMenuName());
            /*
             配置不隐藏路由
             */
            routerVO.setHidden(false);
            /*
              配置路径
             */
            if(menu.getMenuType().equals(MenuTypeEnum.TYPE_DIR.getType())){
                routerVO.setPath("/"+menu.getPath());
            }else {
                routerVO.setPath(menu.getPath());
            }

            /*
              如果是非空
             */
            if(Validator.isNotEmpty(menu.getComponent())){
                routerVO.setComponent(menu.getComponent());
            }else {
                routerVO.setComponent("Layout");
            }

            /*
              构建 Meta
             */
            MetaVO meta = new MetaVO();
            meta.setIcon(menu.getIcon());
            meta.setTitle(menu.getMenuName());
            meta.setNoCache(true);
            routerVO.setMeta(meta);
            Set<SysMenu> childrenMenus = menu.getChildren();
            if (Validator.isNotEmpty(childrenMenus) && childrenMenus.size() > 0 && menu.getMenuType().equals(MenuTypeEnum.TYPE_DIR.getType())) {
                // 存在子菜单 配置参数
                routerVO.setAlwaysShow(true);
                routerVO.setRedirect("noRedirect");
                //构建子路由
                routerVO.setChildren(buildMenus(new ArrayList<>(childrenMenus)));
            }
            routers.add(routerVO);
        }

        return routers;
    }

    @Override
    public List<RouterVO> buildMenus(List<SysMenu> menus, List<Long> menuIds) {
        List<RouterVO> routers = new LinkedList<RouterVO>();

        for(SysMenu menu:menus){
            RouterVO routerVO = new RouterVO();
            // 是否隐藏对应组件
            //routerVO.setIsHidden(menu.getVisible().equals(1));
            routerVO.setName(menu.getMenuName());
            /**
             * 配置路径
             */
            if(menu.getMenuType().equals(MenuTypeEnum.TYPE_DIR.getType())){
                routerVO.setPath("/"+menu.getPath());
            }else {
                routerVO.setPath(menu.getPath());
            }

            /**
             * 如果是非空
             */
            if(Validator.isNotEmpty(menu.getComponent())){
                routerVO.setComponent(menu.getComponent());
            }else {
                routerVO.setComponent("Layout");
            }

            /**
             * 构建 Meta
             */
            MetaVO meta = new MetaVO();
            meta.setIcon(menu.getIcon());
            meta.setTitle(menu.getMenuName());
            // 配置 是否缓存
            //metaVO.setNoCache(menu.getIsCache().equals(0));
            routerVO.setMeta(meta);
            Set<SysMenu> cmenus = menu.getChildren();
            if (Validator.isNotEmpty(cmenus) && cmenus.size() > 0 && menu.getMenuType().equals(MenuTypeEnum.TYPE_DIR.getType())) {
                routerVO.setAlwaysShow(true);
                routerVO.setRedirect("noRedirect");
                //构建子路由
                routerVO.setChildren(buildMenus(new ArrayList<>(cmenus),menuIds));
            }
            if (menu.getMenuType().equals(MenuTypeEnum.TYPE_DIR.getType()) && null != routerVO.getChildren() && routerVO.getChildren().size() !=0){
                //log.info("目录{}创建",menu.getMenuName());
                //如果是目录
                routers.add(routerVO);
            } else if (menu.getMenuType().equals(MenuTypeEnum.PAGE_VIEW.getType()) && menuIds.contains(menu.getId())){
                //log.info("菜单{}创建",menu.getMenuName());
                //如果是菜单
                routers.add(routerVO);
            }

        }

        return routers;
    }


    @Override
    public List<SysMenu> getMenusByPermsIn(List<String> permsList) {
        return dao.findByPermsIn(permsList);
    }
}

